/*!
 Temelia - General tree interface. This interface exports two types of trees: fixed size
 children number trees, with vector backbone; variable size children number trees, with
 linked list backbone.

 Copyright (C) 2008, 2009 Ceata (http://cod.ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef TREE_H_
#define TREE_H_

struct _tree_node_t;
typedef struct _tree_node_t *tree_t;

/*!
 * @brief Constructor - creates a tree containing a node with given key.
 * Complexity O(1)
 *
 * @param Key
 * @param 0 for vector backbone and 1 for linked list backbone
 */
DECLSPEC tree_t tree_new(void *key, int variable_children);

/*!
 * @brief Destructor - deletes node.
 * Complexity O(1)
 *
 * @param Tree node
 */
DECLSPEC void tree_delete_node(tree_t node);

/*!
 * @brief Destructor - deletes tree, doing recursive calls of tree_delete_node.
 * Complexity O(n)
 *
 * @param Tree
 */
DECLSPEC void tree_delete(tree_t tree);

/*!
 * @brief Returns variable children size parameter.
 * Complexity O(1)
 *
 * @param Tree
 */
DECLSPEC int tree_get_type(tree_t tree);

/*!
 * @brief Sets variable tree children size parameter; you must
 * know what you're doing because Temelia, based on this parameter,
 * allocates/deallocates/uses specific memory (vector_t or linked_list_t).
 *
 * @param Tree
 */
DECLSPEC void tree_set_type(tree_t tree, int variable_children);

/*!
 * @brief Sets key stored in node.
 * Complexity O(1)
 *
 * @param Node
 * @param Key
 */
DECLSPEC void tree_set_key(tree_t node, void *key);

/*!
 * @brief Returns the key stored in node.
 * Complexity O(1)
 *
 * @param Node
 */
DECLSPEC void *tree_get_key(tree_t node);

/*!
 * @brief Returns node's parent.
 * Complexity O(1)
 *
 * @param Node
 */
DECLSPEC tree_t tree_get_parent(tree_t node);

/*!
 * @brief Sets a parent-child link between two nodes.
 * Complexity O(1)
 *
 * @param Parent node
 * @param Child node
 */
DECLSPEC void tree_set_parent(tree_t parent, tree_t child);

/*!
 * @brief Adds a child to node.
 * Complexity O(1)
 *
 * @param Parent
 * @param Child
 */
DECLSPEC void tree_add_child(tree_t node, tree_t child);

/*!
 * @brief Removes a child from a node. It leaves a NULL parent to the child and then
 * returns the reference.
 * Complexity O(1)
 *
 * @param Parent
 * @param Child node
 */
DECLSPEC tree_t tree_remove_child(tree_t node, int index);

/*!
 * @brief Removes this node from it's parent. It leaves him a NULL parent.
 * Complexity O(1)
 *
 * @param Node
 */
DECLSPEC void tree_remove_from_parent(tree_t node);

/*!
 * @brief Returns the children of node. Cast it
 * to linked_list_t or vector_t, depending on
 * what you passed to constructor.
 * Complexity O(1)
 *
 * @param Node
 */
DECLSPEC void *tree_get_children(tree_t node);

/*!
 * @brief Returns the children number of node.
 * Complexity O(1)
 *
 * @param Node
 */
DECLSPEC int tree_get_children_number(tree_t node);

/*!
 * @brief Returns the child of node, given by index.
 * Complexity O(1)
 *
 * @param Node
 */
DECLSPEC tree_t tree_get_child(tree_t node, int index);

/*!
 * @brief Checks if node is empty.
 * Complexity O(1)
 *
 * @param Node
 */
DECLSPEC int tree_is_empty(tree_t node);

/*!
 * @brief Checks if node is leaf.
 * Complexity O(1)
 *
 * @param Node
 */
DECLSPEC int tree_is_leaf(tree_t node);

/*!
 * @brief Returns the height of node.
 * Complexity O(size)
 *
 * @param Node
 */
DECLSPEC int tree_get_height(tree_t node);

/*!
 * @brief Returns the root of node.
 * Complexity O(size)
 *
 * @param Node
 */
DECLSPEC tree_t tree_get_root(tree_t node);

/*!
 * @brief Returns the size of tree - number of nodes.
 * Complexity O(size)
 *
 * @param Tree
 */
DECLSPEC int tree_get_size(tree_t tree);

#endif /* TREE_H */
